앵귤러2의 가드를 사용해서, 로그인 서비스를 만들어보자.
로그인 페이지
ngIf 지시자를 활용해 화면 표시 상태 결정.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import { Component } from '@angular/core'; import { Router, NavigationExtras } from '@angular/router'; import { AuthService } from './auth.service';
@Component({ template: ` <h3>LOGIN</h3> {{message}} <p> <input type="text" [(ngModel)]="userId" placeholder="사용자 아이디" *ngIf="!authService.isLogin"> <button (click)="login()" *ngIf="!authService.isLogin">로그인</button> <button (click)="logout()" *ngIf="authService.isLogin">로그아웃</button> </p>` }) export class LoginComponent { message: string; userId: string;
constructor(public authService: AuthService, public router: Router) { this.setMessage(); }
setMessage() { this.message = (this.authService.isLogin ? this.authService.userId + '님 환영합니다.' : '로그인 필요'); }
private doLogin() { this.setMessage(); if (this.authService.isLogin) { let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/admin'; let navigationExtras: NavigationExtras = { preserveQueryParams: true, preserveFragment: true }; this.router.navigate([redirect], navigationExtras); } else { alert('로그인을 할 수 없습니다.'); } }
login() { if (!this.userId) { alert('id를 입력해주세요'); return; } this.message = '로그인을 진행해주세요';
return this.authService.checkId(this.userId).then(children => { if (children) { this.authService.login(this.userId).subscribe(() => this.doLogin()); } else { alert('아이디가 없습니다'); } this.setMessage(); }); }
logout() { this.authService.logout(); this.setMessage(); } }
|
router의 navigate 함수를 통해 로그인 성공시, 페이지 이동.
로그인 버튼을 누르면 login()
메서드가 실행, authService.checkId()
실행.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/delay';
export class User { constructor(public id: number, public name: string) { } }
const USERS = [ new User(1, '첫번째 사용자'), new User(2, '두번째 사용자'), new User(3, '세번째 사용자') ];
export let userPromise = Promise.resolve(USERS);
@Injectable() export class AuthService { isLogin: boolean = false; redirectUrl: string; userId: string;
checkId(userId: string): Promise<User> { return userPromise .then(children => children.find(children => children.id === +userId)); }
login(userId: string): Observable<boolean> { return Observable.of(true).delay(500).do(val => this.isLogin = true).do(val => this.userId = userId); }
logout(): void { this.isLogin = false; } }
|
시뮬레이션을 위해 목객체 사용.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateChild, NavigationExtras, CanLoad, Route } from '@angular/router'; import { AuthService } from './auth.service';
@Injectable() export class AuthGuard implements CanActivate, CanActivateChild, CanLoad { constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { let url: string = state.url; return this.checkLogin(url); }
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { return this.canActivate(route, state); }
canLoad(route: Routce): boolean { let url = `/${route.path}`; if(window.confirm("자식 라우트가 모두 로드 되었습니다. 진행하시겠습니까?")){ return this.checkLogin(url); }else{ return false; } }
checkLogin(url: string): boolean { if (this.authService.isLogin) { return true; } this.authService.redirectUrl = url; let sessionId = 1234;
let navigationExtras: NavigationExtras = { queryParams: { 'session_id': sessionId }, fragment: 'anchor' };
this.router.navigate(['/login'], navigationExtras); return false; } }
|
URL에 세션 매개변수 정보를 전달하기 위해, NavigationExtras를 사용. session_id와 앵커를 url에 붙임. (결과 : http://localhostL4200/login?session_id=1234#anchor)
Reference
쉽고 빠르게 배우는 Angular2 프로그래밍 - 정진욱 지음